#include "Constantes.h"
#include "Semaforo.h"

Semaforo::Semaforo(char* nombre, char letra, int cantidad_en_conjunto) {

	this->cantidad_semaforos = cantidad_en_conjunto;
	key_t clave = ftok(nombre, letra);
	//TODO Analizar posible error
	this->id = semget(clave, this->cantidad_semaforos, 0666 | IPC_CREAT);
	//TODO Analizar posible error
}

int Semaforo::inicializar(int valoresIniciales[]) {

	union semnum {
		int val;
		struct semid_ds* buf;
		ushort* array;
	};

	semnum init;

	int resultado = 0;
	int i = this->cantidad_semaforos - 1;
	for (; i >= 0; i--) {
		init.val = valoresIniciales[i];
		resultado = semctl(this->id, i, SETVAL, init);
		//TODO Analizar posible error
	}

	return resultado;
}

int Semaforo::p(int id_sem, int decremento) {

	struct sembuf operacion;

	operacion.sem_num = id_sem; // numero de semaforo
	operacion.sem_op = 0 - decremento; // restar <decremento> al semaforo
	operacion.sem_flg = SEM_UNDO;

	int resultado = semop(this->id, &operacion, 1);
	return resultado;
}

int Semaforo::v(int id_sem, int incremento) {

	struct sembuf operacion;

	operacion.sem_num = id_sem; // numero de semaforo
	operacion.sem_op = incremento; // sumar <incremento> al semaforo
	operacion.sem_flg = SEM_UNDO;

	int resultado = semop(this->id, &operacion, 1);
	return resultado;
}

void Semaforo::eliminar_todos() {
	int procAdosados = 0;
	/*
	 shmid_ds estado;
	 semctl ( this->shmId,IPC_STAT,&estado );
	 return estado.shm_nattch;
	 */
	if (procAdosados == 0) {

		int i = this->cantidad_semaforos - 1;
		for (; i >= 0; i--) {
			semctl(this->id, i, IPC_RMID);
			//TODO Ver posible error
		}

	}
}

Semaforo::~Semaforo() {
}

